﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace QT.Security
{
    /// <summary>
    /// AES操作类
    /// </summary>
    public class AESHelper
    {
        private static string sKey = @"Q'\rjKE}|<\]#oa:\T.]NJz9D?`$}3Oz"; //密钥
        private static string sIV = @"zTJQ{i5NOAL~aoea"; //密钥向量

        #region 加密

        #region 加密文件

        /// <summary>
        /// AES加密文件
        /// </summary>
        /// <param name="inFile">输入文件</param>
        /// <param name="outFile">输入文件</param>
        /// <param name="Key">加密密钥</param>
        /// <param name="Vector">向量</param>
        /// <returns>bool</returns>
        public static bool AESEncryptFile(string inFile, string outFile, string Key, string Vector)
        {
            FileStream fin = new FileStream(inFile, FileMode.Open, FileAccess.Read);
            FileStream fout = null;
            try
            {
                fout = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write);
            }
            catch
            {
                return false;
            }
            fout.SetLength(0);

            byte[] bin = new byte[100];
            long rdlen = 0;
            long totlen = fin.Length;
            int len;

            Rijndael Aes = Rijndael.Create();
            Aes.Key = Encoding.UTF8.GetBytes(Key);
            Aes.IV = Encoding.UTF8.GetBytes(Vector);

            try
            {
                CryptoStream encStream = new CryptoStream(fout, Aes.CreateEncryptor(), CryptoStreamMode.Write);

                while (rdlen < totlen)
                {
                    len = fin.Read(bin, 0, 100);
                    encStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }

                encStream.Close();
            }
            catch
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// AES加密文件
        /// </summary>
        /// <param name="inFile">输入文件</param>
        /// <param name="outFile">输入文件</param>
        /// <param name="Key">加密密钥</param>
        /// <returns>bool</returns>
        public static bool AESEncryptFile(string inFile, string outFile, string Key)
        {
            return AESEncryptFile(inFile, outFile, Key, sIV);
        }

        /// <summary>
        /// AES加密文件
        /// </summary>
        /// <param name="inFile">输入文件</param>
        /// <param name="outFile">输入文件</param>
        /// <returns>bool</returns>
        public static bool AESEncryptFile(string inFile, string outFile)
        {
            return AESEncryptFile(inFile, outFile, sKey, sIV);
        }

        #endregion

        #region 加密字符串

        /// <summary>
        /// AES加密字符串
        /// </summary>
        /// <param name="encryptValue">被加密的明文</param>
        /// <param name="Key">密钥</param>
        /// <param name="Vector">向量</param>
        /// <returns>密文</returns>
        public static string AESEncrypt(string encryptValue, String Key, String Vector)
        {

            Byte[] Cryptograph = null; // 加密后的密文
            Byte[] Data = Encoding.UTF8.GetBytes(encryptValue);

            MemoryStream ms = new MemoryStream();

            Rijndael Aes = Rijndael.Create();
            Aes.Key = Encoding.UTF8.GetBytes(Key);
            Aes.IV = Encoding.UTF8.GetBytes(Vector);
            try
            {
                CryptoStream cs = new CryptoStream(ms, Aes.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(Data, 0, Data.Length);
                cs.FlushFinalBlock();
                Cryptograph = ms.ToArray();
                cs.Close();
                ms.Close();
            }
            catch
            {
                return null;
            }

            return Convert.ToBase64String(Cryptograph);
        }

        /// <summary>
        /// AES加密字符串
        /// </summary>
        /// <param name="encryptValue">被加密的明文</param>
        /// <param name="Key">密钥</param>
        /// <returns>密文</returns>
        public static string AESEncrypt(string encryptValue, String Key)
        {
            return AESEncrypt(encryptValue, Key, sIV);
        }

        /// <summary>
        /// AES加密字符串
        /// </summary>
        /// <param name="encryptValue">被加密的明文</param>
        /// <returns>密文</returns>
        public static string AESEncrypt(string encryptValue)
        {
            return AESEncrypt(encryptValue, sKey, sIV);
        }

        #endregion

        #endregion

        #region 解密

        #region 解密文件

        /// <summary>
        /// AES解密文件
        /// </summary>
        /// <param name="inFile">输入文件</param>
        /// <param name="outFile">输入文件</param>
        /// <param name="Key">加密密钥</param>
        /// <param name="Vector">向量</param>
        /// <returns>bool</returns>
        public static bool AESDecryptFile(string inFile, string outFile, string Key, string Vector)
        {
            FileStream fin = new FileStream(inFile, FileMode.Open, FileAccess.Read);
            FileStream fout = null;
            try
            {
                fout = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write);
            }
            catch
            {
                return false;
            }
            fout.SetLength(0);

            byte[] bin = new byte[100];
            long rdlen = 0;
            long totlen = fin.Length;
            int len;

            Rijndael Aes = Rijndael.Create();
            Aes.Key = Encoding.UTF8.GetBytes(Key);
            Aes.IV = Encoding.UTF8.GetBytes(Vector);

            try
            {
                CryptoStream decStream = new CryptoStream(fout, Aes.CreateDecryptor(), CryptoStreamMode.Write);

                while (rdlen < totlen)
                {
                    len = fin.Read(bin, 0, 100);
                    decStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }

                decStream.Close();
            }
            catch
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// AES解密文件
        /// </summary>
        /// <param name="inFile">输入文件</param>
        /// <param name="outFile">输入文件</param>
        /// <param name="Key">加密密钥</param>
        /// <returns>bool</returns>
        public static bool AESDecryptFile(string inFile, string outFile, string Key)
        {
            return AESDecryptFile(inFile, outFile, Key, sIV);
        }

        /// <summary>
        /// AES解密文件
        /// </summary>
        /// <param name="inFile">输入文件</param>
        /// <param name="outFile">输入文件</param>
        /// <returns>bool</returns>
        public static bool AESDecryptFile(string inFile, string outFile)
        {
            return AESDecryptFile(inFile, outFile, sKey, sIV);
        }

        #endregion

        #region 解密字符串

        /// <summary>
        /// AES解密字符串
        /// </summary>
        /// <param name="decryptedValue">被解密的密文</param>
        /// <param name="Key">密钥</param>
        /// <param name="Vector">向量</param>
        /// <returns>明文</returns>
        public static string AESDecrypt(String decryptedValue, String Key, String Vector)
        {
            Byte[] original = null; // 解密后的明文 
            Byte[] Data = Convert.FromBase64String(decryptedValue);

            MemoryStream ms = new MemoryStream();

            Rijndael Aes = Rijndael.Create();
            Aes.Key = Encoding.UTF8.GetBytes(Key);
            Aes.IV = Encoding.UTF8.GetBytes(Vector);
            try
            {
                CryptoStream cs = new CryptoStream(ms, Aes.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(Data, 0, Data.Length);
                cs.FlushFinalBlock();
                original = ms.ToArray();
                cs.Close();
                ms.Close();
            }
            catch
            {
                return null;
            }

            return Encoding.UTF8.GetString(original);
        }

        /// <summary>
        /// AES解密字符串
        /// </summary>
        /// <param name="decryptedValue">被解密的密文</param>
        /// <param name="Key">密钥</param>
        /// <returns>明文</returns>
        public static string AESDecrypt(string decryptedValue, string Key)
        {
            return AESDecrypt(decryptedValue, Key, sIV);
        }

        /// <summary>
        /// AES解密字符串
        /// </summary>
        /// <param name="decryptedValue">被解密的密文</param>
        /// <returns>明文</returns>
        public static string AESDecrypt(string decryptedValue)
        {
            return AESDecrypt(decryptedValue, sKey, sIV);
        }

        #endregion

        #endregion
    }
}
